Шаг 3. Сжимаем коммиты
В одной из прошлых демонстраций мы сжимали коммиты с помощью команды git merge и опции --squash. Теперь рассмотрим другой вариант, который позволяет сжать коммиты, находясь в текущей ветке. И в этом нам поможет команда git rebase.
Сама по себе команда ничего не делает, если её просто прописать в текущей ветке. Чтобы сжать коммиты, понадобится дополнительная опция --interactive, или сокращённо -i.
Важно: большинство команд в интерактивном режиме меняют историю коммитов. К примеру, у вас есть три коммита. Если вы примените команду только к третьему от вершины всех коммитов, то хэш будет изменён не только у него, но и у двух других коммитов. Поэтому команды нужно выполнять только на тех коммитах, которые ещё не отправлены в удалённый репозиторий. Будьте внимательны, так как любое неверное действие может привести к серьёзным последствиям, которые будет сложно решить.
Теперь посмотрим, как работает команда.
Для начала переключимся обратно на ветку task/rebase с помощью команды git switch task/rebase.
Далее нам нужно внести несколько изменений. Сначала добавим элемент <h2> с текстом «Это заголовок второго уровня».
Добавим это изменение в индекс с помощью команды git add --all, а затем зафиксируем его с помощью команды git commit --message "feat: h2 title added".
Далее внесём ещё одно изменение. Добавим элемент <h3> с текстом «Это заголовок третьего уровня».
Точно так же добавим изменение в индекс — git add --all, а затем зафиксируем его — git commit --message "feat: h3 title added".
После этого выведем три последних коммита — git log --oneline -3. Первые два нам понадобятся, чтобы сравнить, как изменился хэш коммита. Третий нужен для следующей команды.
Теперь нужно сжать два последних коммита, объединив их в один. Воспользуемся командой git rebase --interactive b01ad3e. После опции --interactive мы указали хэш третьего коммита, так как в данном случае именно он будет общим для двух последних. Поэтому, если вы хотите изменить какой-то коммит или группу коммитов, нужно всегда указывать предыдущий коммит.
Открылся специальный todo-файл Git, в котором мы будем указывать нужные команды. Одна из команд уже прописана для наших двух коммитов — pick. Она ничего не даёт — просто позволяет использовать коммит, и если мы сейчас закроем файл, то ничего не изменится.
Самыми часто используемыми командами являются: pick, reword, squash, fixup, drop и edit. Сейчас мы подробно их разберём, не считая pick — про неё уже рассказали.
reword ® — позволяет задействовать коммит и поменять его текст. Полезная команда, если вы сделали коммит, но через какое-то время поняли, что ошиблись и неверно написали текст.
Конечно, можно отменить коммит и снова его создать, но это слишком долго. К тому же, если коммит не последний, тактика с отменой не подойдёт — мы удалим не только нужный коммит, но и другие.
squash (s) — позволяет задействовать коммит и объединить его с предыдущим. С помощью этой команды можно также изменить текст коммита.
Перед squash обязательно должна быть команда pick, иначе будет ошибка. Также ошибка появится, если pick будет после squash, так как объединить коммит можно только с предыдущим.
fixup (f) — делает то же самое, что и squash, но не позволяет изменить текст коммита. То есть текст будет взят из коммита, который помечен командой pick.
drop (d) — позволяет полностью удалить коммит.
edit (e) — позволяет задействовать коммит, но после закрытия todo-файла перебазирование будет приостановлено, чтобы вы могли добавить дополнительные файлы в последний коммит.
Хотя данная команда попала в список часто используемых, пользы от неё не так много, как, например, от команды squash.
Мы разобрались с основными командами, теперь продолжим сжатие. Для первого коммита мы так и оставим команду pick, а вот для второго вместо pick напишем squash.
Далее сохраняем файл и жмём на крестик рядом с названием файла. Через несколько секунд откроется ещё один файл под названием COMMIT_EDITMSG. В нём нужно изменить текст только первого коммита, а второй менять необязательно.
Точно так же сохраняем файл и жмём на крестик, чтобы его закрыть. Всё, коммиты объединены. Об этом говорит вывод Git.
Теперь пропишем команду git log --oneline -2, чтобы посмотреть хэш нового коммита и сравнить его со старым.
Хэш коммита тоже изменился. До сжатия он был 388a619, а сейчас 6625576. Мы частично изменили историю коммитов, поэтому важно такие манипуляции проводить только с теми коммитами, которые не отправлены в удалённый репозиторий.
Теперь переключимся на основную ветку main с помощью команды git switch -.
Нам не нужны тестовые заголовки, поэтому удалим временную ветку task/rebase— git branch -D task/rebase. Удаляем ветку принудительно, так как на ней есть изменения, которых нет на ветке main.
И в конце отправим наши прошлые изменения в удалённый репозиторий — git push.
Всё изменения отправлены в удалённый репозиторий.